#参考CSDN的一篇blog完成
import numpy as np
import sklearn.datasets
import matplotlib.pyplot as plot
from sklearn.manifold import Isomap
from sklearn.metrics import confusion_matrix
from sklearn.datasets import load_digits
from sklearn.metrics import accuracy_score
def sigmoid(inx):
    if inx >= 0:  
        return 1.0 / (1 + np.exp(-inx))
    else:
        return np.exp(inx) / (1 + np.exp(inx))

def train(date,label,weights,b, num_iteration=150):
    """随机梯度上升算法
     Args:
        data (numpy.ndarray): 训练数据集
        labels (numpy.ndarray): 训练标签
        num_iteration (int): 迭代次数
        """

    alpha = 0.01
    data_num, n = np.shape(data)
    for k in range(10):
        for j in range(num_iteration):
            data_index = list(range(data_num))
            for i in range(data_num):
                rand_index = int(np.random.uniform(0, len(data_index)))
                pos=0
                if k==label[rand_index]:
                    pos=1
                error = pos - sigmoid(sum(data[rand_index,:] * weights[k,:] +b[k]))
                weights[k,:] += alpha * error * data[rand_index,:]
                b[k] += alpha * error
                del(data_index[rand_index])
    return weights,b
def predict(weights,b, predict_data):
    """prediction function"""
    num,item=np.shape(predict_data)
    result=np.zeros((num,2))
    for i in range(num):
        for j in range(10):
            if (np.sum(predict_data[i,:] * weights[j,:])+b[j])>result[i,0]:
                result[i,0]=np.sum(data[i,:] * weights[j,:])
                result[i,1]=j
    return np.array(result)

digits = load_digits()
print(np.shape(digits.data))
iso = Isomap(n_neighbors=5, n_components=16)

data = iso.fit_transform(digits.data)


label=digits.target
data_num, n = np.shape(data)

weights=np.ones((10,n))

b=np.ones(10)

self=train(data,label,weights,b,200)
predict_result=predict(weights,b,data)
accre = accuracy_score(label, predict_result[:,1])
print("accuracy = %f" % (accre))
santch = confusion_matrix(label,predict_result[:,1])
#可视化
plot.matshow(santch)

plot.title(u'Confusion Matrix')
plot.colorbar()

plot.ylabel(u'Groundtruth')

plot.xlabel(u'Predict')
plot.show()

from sklearn.datasets import load_digits
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from sklearn.manifold import Isomap

import matplotlib.pyplot as plot

# load digital data
digits, dig_label = load_digits(return_X_y=True)


feature_trans = False
if feature_trans:
    iso = Isomap(n_neighbors=5, n_components=8)
    digits = iso.fit_transform(digits)

# calculate train/test data number
N = len(digits)
N_train = int(N*0.8)
N_test = N - N_train

# split train/test data
x_train = digits[:N_train, :]
y_train = dig_label[:N_train]
x_test  = digits[N_train:, :]
y_test  = dig_label[N_train:]

# FIXME: need to use Isomap to transform data

# do logistic regression
lr=LogisticRegression()
lr.fit(x_train,y_train)

pred_train = lr.predict(x_train)
pred_test  = lr.predict(x_test)

# calculate train/test accuracy
acc_train = accuracy_score(y_train, pred_train)
acc_test = accuracy_score(y_test, pred_test)

score_train = lr.score(x_train, y_train)
score_test  = lr.score(x_test, y_test)
print(" score_test = %f" % ( score_test))
cm = confusion_matrix(y_test,pred_test)

plot.matshow(cm)
plot.title(u'Confusion Matrix_sklearn_acc = %f' % (score_test))
plot.colorbar()
plot.ylabel(u'Groundtruth')
plot.xlabel(u'Predict')
plot.show()

